#pragma once

struct GLVertexBuffer;

struct GLVertexArray
{
	struct VertexAttachment
	{
		GLVertexBuffer* vb;
		uint location;
		uint size;
		GLenum type;
		uint offset;
		uint stride;
		bool instanced;

		VertexAttachment(GLVertexBuffer* vb, uint location, uint size, GLenum type, uint offset, uint stride, bool instanced) :
			vb(vb),
			location(location),
			size(size),
			type(type),
			offset(offset),
			stride(stride),
			instanced(instanced)
		{}
	};

	std::vector<GLVertexBuffer*> ownedBuffers;
	std::vector<VertexAttachment> arrayBuffers;
	GLenum topology;
	uint verticesCount;
	const std::string name;
	uint handle;
	GLVertexBuffer* indexBuffer;
	int instancing;

	GLVertexArray(const std::string& name, GLenum topology, uint verticesCount) :
		name(name),
		handle(0),
		topology(topology),
		verticesCount(verticesCount),
		indexBuffer(NULL),
		instancing(-1)
	{}
};

struct VertexDeclaration;
extern const VertexDeclaration g_vertexDeclarations[];

class VertexArrayWrapper
{
protected:
	VertexArrayWrapper(void);
	~VertexArrayWrapper(void);

	static GLVertexArray*	_boundVertexArray;
	static int				_vertexArrayCount;
	static GLVertexBuffer*	_nextDrawInstancingData;
	static std::map<std::string, GLVertexArray*>	_vertexArraysMap;

	static void				AttachVertexBuffer(GLVertexBuffer* vb, uint location, GLenum type, uint size, uint offset, uint stride, bool instanced = false);
	static void				AttachIndexBuffer(GLVertexBuffer* vb);

public:
	static GLVertexArray*	GenVertexArray(const std::string& name, GLenum primitive, uint primitiveCount);
	static void				DeleteVertexArray(GLVertexArray** vao);
	static void				AttachBuffer(GLVertexBuffer* vb);

	static void				UniqueBufferOwner(GLVertexArray* vao, GLVertexBuffer* vb);

	static void				BindVertexArray(GLVertexArray* vao, bool force = false);
	static void				UnbindVertexArray();

	static void				DrawVertexArray(uint instances = 0);
	static void				SetNextDrawInstancingData(GLVertexBuffer* vb);
};

